import router from '@/router'
import { useUserStore } from '@/store/user'
import { usePermissionStore } from '@/store/permission'
import { ElMessage } from 'element-plus'
import { getToken } from '@/utils/auth'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { RouteLocationNormalized, RouteRecordRaw } from 'vue-router'

NProgress.configure({ showSpinner: false })

const whiteList = ['/login', '/auth-redirect']

router.beforeEach(async(to: RouteLocationNormalized, from: RouteLocationNormalized, next) => {
  NProgress.start()
  const hasToken = getToken()

  if (hasToken) {
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    } else {
      const userStore = useUserStore()
      const hasRoles = userStore.roles && Array.isArray(userStore.roles) && userStore.roles.length > 0
      
      if (hasRoles) {
        next()
      } else {
        try {
          // 获取用户信息
          const { roles } = await userStore.getInfo()
          
          // 确保用户信息获取成功
          if (!roles || !Array.isArray(roles) || roles.length === 0) {
            throw new Error('用户角色信息无效')
          }
          
          // 生成路由
          const permissionStore = usePermissionStore()
          const accessRoutes = await permissionStore.generateRoutes(roles)
          
          // 确保路由生成成功
          if (!accessRoutes || !Array.isArray(accessRoutes)) {
            throw new Error('路由生成失败')
          }
          
          // 添加路由
          accessRoutes.forEach((route: RouteRecordRaw) => {
            router.addRoute(route)
          })
          
          // 确保路由添加完成
          next({ ...to, replace: true })
        } catch (error: any) {
          console.error('Permission check error:', error)
          await userStore.resetToken()
          ElMessage.error(error?.message || '认证失败')
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})

/**
 * @param {Array} value
 * @returns {Boolean}
 * @example see @/views/permission/directive.vue
 */
export default function checkPermission(value: string[]): boolean {
  if (value && Array.isArray(value) && value.length > 0) {
    const userStore = useUserStore()
    const roles = userStore.roles || []
    
    if (!roles || !Array.isArray(roles)) {
      console.error('Invalid roles:', roles)
      return false
    }
    
    return roles.some(role => value.includes(role))
  }
  console.error(`need roles! Like v-permission="['admin','editor']"`)
  return false
}
